package com.ms.p2p.plugin.payment.fuyou;


import com.ms.common.exception.NoticeException;
import com.ms.common.utils.MsDateUtils;
import com.ms.p2p.entity.account.AccountRecharge;
import com.ms.p2p.entity.system.PayMethod;
import com.ms.p2p.plugin.payment.AbstractPaymentPlugin;
import com.ms.p2p.plugin.payment.IPaymentEvent;
import com.ms.p2p.plugin.payment.fuyou.util.DESCoderFUIOU;
import com.ms.p2p.plugin.payment.fuyou.util.FyRechargeWebBean;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class FuyouWapPayment extends AbstractPaymentPlugin implements IPaymentEvent {


    @Override
    public void register() {

    }

    @Override
    public String onPay(Integer userId, BigDecimal money, HashMap other,HttpServletRequest request) throws Exception {
        PayMethod payment = payMethodService.findById(getId());
        AccountRecharge rechargeOrder = BuildReCharge(userId, money, payment);
        if(other.get("bank_card")==null){
            throw  new NoticeException("银行卡号不能为空");
        }
        FyRechargeWebBean fyRechargeWebBean = new FyRechargeWebBean();
        fyRechargeWebBean.setEnctp("1");
        fyRechargeWebBean.setMchnt_cd(payMethodValueService.findByName("fuyou.mchnt_cd").getParamValue());
        fyRechargeWebBean.setType("10");
        fyRechargeWebBean.setVersion("2.0");
        fyRechargeWebBean.setLogo_tp("0");
        fyRechargeWebBean.setMchnt_order_id(rechargeOrder.getTrade_no());
        fyRechargeWebBean.setUser_id(userId+"");
        fyRechargeWebBean.setAmt(new BigDecimal(100).multiply(money).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
        fyRechargeWebBean.setBank_card(other.get("bank_card")+"");//银行卡号
        String weburl = settingService.findValueByCode("weburl");
        String urlStr = "http://" + weburl + "";
        String noticeurl =  payMethodValueService.findByName("fuyou.wapretutn").getParamValue();
        String backurl =  payMethodValueService.findByName("fuyou.wapnotify").getParamValue();
        noticeurl = urlStr + noticeurl;
        backurl = urlStr + backurl;
        fyRechargeWebBean.setBack_url(backurl);
        fyRechargeWebBean.setRe_url(noticeurl);
        fyRechargeWebBean.setHome_url(noticeurl);
        fyRechargeWebBean.setName(other.get("realname")+"");//实名
        fyRechargeWebBean.setId_type("0");
        fyRechargeWebBean.setId_no(other.get("id_card_no")+"");
        fyRechargeWebBean.setRem1("");
        fyRechargeWebBean.setRem2("");
        fyRechargeWebBean.setRem3("");
        fyRechargeWebBean.setSign_tp("md5");

        String signDataStr = fyRechargeWebBean.getType() + "|" + fyRechargeWebBean.getVersion()+ "|" +fyRechargeWebBean.getMchnt_cd()+ "|" +fyRechargeWebBean.getMchnt_order_id()+ "|" +
                fyRechargeWebBean.getUser_id()+ "|" +fyRechargeWebBean.getAmt()+ "|" +fyRechargeWebBean.getBank_card()+ "|" +
                fyRechargeWebBean.getBack_url()+ "|" +fyRechargeWebBean.getName()+ "|" +fyRechargeWebBean.getId_no()+ "|"
                +fyRechargeWebBean.getId_type()+ "|" +fyRechargeWebBean.getLogo_tp()+ "|" +fyRechargeWebBean.getHome_url()+ "|" +
                fyRechargeWebBean.getRe_url()+ "|" +payMethodValueService.findByName("fuyou.webkey").getParamValue();
        String sign = MD5Encode(signDataStr);
        fyRechargeWebBean.setSign(sign);

        String fm = new StringBuffer().append("<ORDER>")
                .append("<MCHNTCD>").append(fyRechargeWebBean.getMchnt_cd()).append("</MCHNTCD>")
                .append("<TYPE>").append(fyRechargeWebBean.getType()).append("</TYPE>")
                .append("<VERSION>").append(fyRechargeWebBean.getVersion()).append("</VERSION>")
                .append("<LOGOTP>").append(fyRechargeWebBean.getLogo_tp()).append("</LOGOTP>")
                .append("<MCHNTORDERID>").append(fyRechargeWebBean.getMchnt_order_id()).append("</MCHNTORDERID>")
                .append("<USERID>").append(fyRechargeWebBean.getUser_id()).append("</USERID>")
                .append("<AMT>").append(fyRechargeWebBean.getAmt()).append("</AMT>")
                .append("<BANKCARD>").append(fyRechargeWebBean.getBank_card()).append("</BANKCARD>")
                .append("<BACKURL>").append(fyRechargeWebBean.getBack_url()).append("</BACKURL>")
                .append("<REURL>").append(fyRechargeWebBean.getRe_url()).append("</REURL>")
                .append("<HOMEURL>").append(fyRechargeWebBean.getHome_url()).append("</HOMEURL>")
                .append("<NAME>").append(fyRechargeWebBean.getName()).append("</NAME>")
                .append("<IDTYPE>").append(fyRechargeWebBean.getId_type()).append("</IDTYPE>")
                .append("<IDNO>").append(fyRechargeWebBean.getId_no()).append("</IDNO>")
                .append("<REM1>").append(fyRechargeWebBean.getRem1()).append("</REM1>")
                .append("<REM2>").append(fyRechargeWebBean.getRem2()).append("</REM2>")
                .append("<REM3>").append(fyRechargeWebBean.getRem3()).append("</REM3>")
                .append("<SIGNTP>").append(fyRechargeWebBean.getSign_tp()).append("</SIGNTP>")
                .append("<SIGN>").append(fyRechargeWebBean.getSign()).append("</SIGN>")
                .append("</ORDER>").toString();

        fyRechargeWebBean.setFm(DESCoderFUIOU.desEncrypt(fm, DESCoderFUIOU.getKeyLength8(payMethodValueService.findByName("fuyou.webkey").getParamValue())));

        LinkedHashMap map = new LinkedHashMap();
        map.put("ENCTP",1);
        map.put("MCHNTCD",fyRechargeWebBean.getMchnt_cd());
        map.put("type",10);
        map.put("VERSION","2.0");
        map.put("logo_tp",0);
        map.put("mchnt_order_id",rechargeOrder.getTrade_no());
        map.put("user_id",userId);
        map.put("amt",fyRechargeWebBean.getAmt());
        map.put("bank_card",fyRechargeWebBean.getBank_card());
        map.put("back_url",fyRechargeWebBean.getBack_url());
        map.put("re_url",fyRechargeWebBean.getRe_url());
        map.put("home_url",fyRechargeWebBean.getHome_url());
        map.put("name",fyRechargeWebBean.getName());
        map.put("id_type",fyRechargeWebBean.getId_type());
        map.put("id_no",fyRechargeWebBean.getId_no());

        map.put("sign_tp",fyRechargeWebBean.getSign_tp());
        map.put("rem1","");
        map.put("rem2","");
        map.put("rem3","");
        map.put("sign",fyRechargeWebBean.getSign());
        map.put("FM",fyRechargeWebBean.getFm());


        return buildPostRequest(map, payMethodValueService.findByName("fuyou.wapurl").getParamValue(),request);

    }

    @Override
    public String onReturn(HttpServletRequest request) throws Exception {

        logger.info("——————————————富友H5支付同步回调开始"+ MsDateUtils.getTimeToday());
        String version = nvl(request.getParameter("VERSION"));
        String type = nvl(request.getParameter("TYPE"));
        String response_code = nvl(request.getParameter("RESPONSECODE"));
        String response_msg = nvl(request.getParameter("RESPONSEMSG"));
        String mchnt_cd = nvl(request.getParameter("MCHNTCD"));
        String mchnt_order_id = nvl(request.getParameter("MCHNTORDERID"));
        String order_id = nvl(request.getParameter("ORDERID"));
        String bank_card = nvl(request.getParameter("BANKCARD"));
        String amt = nvl(request.getParameter("AMT"));
        String sign = nvl(request.getParameter("SIGN"));
        String mchnt_key = payMethodValueService.findByName("fuyou.webkey").getParamValue();  //32位的商户密钥

        String signDataStr = type + "|" +
                version + "|" + response_code + "|" + mchnt_cd + "|" + mchnt_order_id + "|" + order_id + "|" +
                amt + "|" + bank_card + "|" + mchnt_key;
        String sign2 = MD5Encode(signDataStr);
        logger.info("signDataStr:"+signDataStr);
        logger.info("sign:"+sign+"-------------------"+sign.length());
        logger.info("sign2:"+sign2+"-----------------"+sign2.length());
        String out_trade_no = mchnt_order_id;

        if ("0000".equals(response_code)) {
            if (sign.trim().equals(sign2.trim())) {
                    String result =  OnlineReturn(out_trade_no, "在线认证充值-富友支付");
                    logger.info("——————————————富友网银支付同步回调成功");
            } else {
                logger.info("——————————————富友H5支付同步回调失败，错误原因：验签失败");
            }
        } else {

            logger.info("——————————————富友H5支付同步回调失败，错误原因："+ response_msg);

        }

       return null;
    }

    @Override
    public String getTradeNo(Map<String, String> params) throws Exception {
        return null;
    }

    @Override
    public String getType() {
        return "1";
    }

    @Override
    //id需要与paymethod id一样
    public String getId() {
        return "55";
    }

    @Override
    //名称需要与包明一样
    public String getName() {
        return "fuyouwap";
    }

    @Override
    public String getVersion() {
        return "1.0.0";
    }

    @Override
    public String getAuthor() {
        return "daimajia";
    }

    @Override
    public void perform(Object... params) {

    }

    public static String MD5Encode(String origin) {
        origin = origin.trim();
        String resultString = null;

        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString.getBytes("UTF-8")));
        } catch (Exception var3) {
            ;
        }

        return resultString;
    }

    public static String byteArrayToHexString(byte[] b) {
        StringBuffer resultSb = new StringBuffer();

        for(int i = 0; i < b.length; ++i) {
            resultSb.append(byteToHexString(b[i]));
        }

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if(b < 0) {
            n = b + 256;
        }

        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    private static final String[] hexDigits = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    public static String nvl(String aStr) {
        if (aStr == null || "null".equals(aStr.trim())) {
            return "";
        } else {
            return aStr.trim().toString();
        }
    }
}
